﻿#pragma once

#include "Controller.h"

#include <boost/signal.hpp>

#include "gameplay/GameplayController.h"
#include "../views/abstract/IApplicationView.h"
#include "../domain/helpers/NetworkException.h"
#include "../utils/gui/Form.h"


namespace Controllers {
	/**
	* Główny kontroler aplikacji.
	* Zajmuje się utowrzeniem kontrolera gry i nadzorem nad nim.
	*/
	class ApplicationController: public Controller
	{
	private:
		Views::IApplicationView* view;
		GameplayController* gameplay_controller;
		Utils::GUI::Form* form;
		bool is_ended;

	public:
		ApplicationController(Utils::GUI::Form*);
		virtual ~ApplicationController();

		/**
		* Rozpoczyna aplikację i pyta o tryb gry
		*/
		void startApp();
		void endApp(); /** Wymusza koniec aplikacji */
		/**
		* Sprawdza czy aplikacja się zakończyła.
		* Aplikacja mogła się zakończyć w przypadku wystąpienia nieobsłużonego wyjątku
		* lub wygranej jednego z graczy
		* @return Prawda, jeśli gra jest zakończona
		*/
		bool isEnded();

		/**
		* Funkcja przechwytująca wyjątek
		* Może zostać użyte z pętli aplikacji do obsługu wyjątku, który wystąpił przy przetwarzaniu zdarzeń.
		*/
		void handleException(std::exception&);
		/**
		* Funkcja przechwytująca wyjątek
		* @see handleException(std::exception&)
		*/
		void handleException(Domain::Helpers::NetworkException&);

	protected:
		void startGame(); /**< Rozpoczyna rozgrywkę */
		void setGameplayControllerEvents(); /**< Ustawia zdarzenia związane z obsługą kontrolera gry */
		/**
		* Ustawia kontroler gry
		* @param mode Tryb gry (lokalny, serwer albo klient)
		*/ 
		void setController(Domain::Configuration::GAME_MODE);
		void gameLost(Players::Player*, Cards::CardSet, Domain::Configuration::GAME_END_REASON); /**< Informuje gracza przegraniu gry */
		void gameWon(Players::Player*, Cards::CardSet, Domain::Configuration::GAME_END_REASON); /**< Informuje gracza wygraniu gry */
	};
}

